<template>
    <el-dialog
        class="custom-modal"
        :title="title"
        :visible.sync="show"
        append-to-body
        top="20vh"
        @open="_open"
        @close="_close"
        @closed="_afterClose"
        v-auto-focus
    >
        <div class="tree-cascader-box">
            <div class="tree-cascader__data-box">
                <div class="tree-cascader__header">
                    <el-input
                        placeholder="请输入内容"
                        prefix-icon="el-icon-search"
                        v-model="search"
                        @input="handleInputChange"
                    >
                    </el-input>
                </div>
                <div class="tree-cascader__body">
                    <el-tree
                        :data="treeData"
                        show-checkbox
                        :check-strictly="checkStrictly"
                        default-expand-all
                        node-key="id"
                        ref="treeRef"
                        highlight-current
                        :filter-node-method="filterNode"
                        :default-checked-keys="value"
                        @check-change="handleNodeClick"
                        :props="defaultProps"
                    >
                    </el-tree>
                </div>
            </div>
            <div class="tree-cascader__data-box">
                <div class="tree-cascader__header">
                    已选择{{selectData.length}}个
                </div>
                <div class="tree-cascader__body">
                    <ul class="tree-cascader__ul">
                        <template v-for="(item,index) in selectData">
                            <li class="tree-cascader__li" :key="item.id" @click="handleDataClick(item, index)">
                                {{item.label}}
                            </li>
                        </template>
                    </ul>
                </div>
            </div>
        </div>
        <div slot="footer" class="dialog-footer">
            <el-button @click="close">取消</el-button>
            <el-button
                class="sure"
                type="primary"
                @click="sure"
                :loading="ajaxLoader"
                >保存</el-button
            >
        </div>
    </el-dialog>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component
export default class TreeCascaderForm extends Vue {
    title = "树形选择器";
    show = false;
    ajaxLoader = false;
    ajaxIndex = 0;
    defaultProps = {
        children: "children",
        label: "label"
    };

    model: any = {};
    search = "";
    options: any[] = [];
    treeData: any[] = [];
    checkStrictly = false;
    // treeData: any[] = [
    //     {
    //         id: 1,
    //         label: "一级 1",
    //         children: [
    //             {
    //                 id: 4,
    //                 label: "二级 1-1",
    //                 children: [
    //                     {
    //                         id: 9,
    //                         label: "三级 1-1-1"
    //                     },
    //                     {
    //                         id: 10,
    //                         label: "三级 1-1-2"
    //                     }
    //                 ]
    //             }
    //         ]
    //     },
    //     {
    //         id: 2,
    //         label: "一级 2",
    //         children: [
    //             {
    //                 id: 5,
    //                 label: "二级 2-1"
    //             },
    //             {
    //                 id: 6,
    //                 label: "二级 2-2"
    //             }
    //         ]
    //     },
    //     {
    //         id: 3,
    //         label: "一级 3",
    //         children: [
    //             {
    //                 id: 7,
    //                 label: "二级 3-1"
    //             },
    //             {
    //                 id: 8,
    //                 label: "二级 3-2"
    //             }
    //         ]
    //     }
    // ];

    selectData: any[] = [];
    value: any[] = [];
    disabledValue: any[] = [];
    filterable = false;
    filterMethod: any = null;
    async _open() {
        this.$emit("onopen");
        this.initData();
    }

    _close() {
        this.$emit("onclose");
    }

    _afterClose() {
        this.$nextTick(function() {
            this.$emit("onafterclose");
            this.$el.remove && this.$el.remove();
        });
    }

    loader(state: boolean) {
        if (state) {
            if (this.ajaxIndex === 0) this.ajaxLoader = true;
            this.ajaxIndex++;
        } else {
            setTimeout(() => {
                this.ajaxIndex--;
                if (this.ajaxIndex === 0) this.ajaxLoader = false;
            }, 300);
        }
    }

    close() {
        this.show = false;
        this.$nextTick(() => {
            this._afterClose();
        });
    }

    async initData() {
        this.loader(true);
        console.log(this.options);
        this.treeData = this.buildTableData(this.options);
        setTimeout(() => {
            this.loader(false);
        }, 300);
    }

    buildTableData(list: any) {
        const res: any[] = [];
        if (list.length === 0) {
            return res;
        }
        list.forEach((cur: any) => {
            const _cur: any = {};
            _cur.label = cur.label || "";
            _cur.id = cur.value || "";
            if (cur.children && cur.children.length > 0) {
                _cur.children = this.buildTableData(cur.children);
            }
            if (this.checkStrictly || !cur.children || cur.children.length === 0) {
                if (this.disabledValue.includes(_cur.id)) {
                    _cur.disabled = true;
                }
                if (this.value.includes(_cur.id)) {
                    const _index = this.selectData.findIndex((selectItem: any) => selectItem.id === _cur.id);
                    if (_index === -1) {
                        this.selectData.push(_cur);
                    }
                }
            }
            res.push(_cur);
        });
        return res;
    }

    async sure() {
        // console.log(this.value);
        this.$emit("sure", {
            value: this.value
        });
    }

    handleInputChange() {
        this.loader(true);
        this.searchResult().then((res: any) => {
            this.loader(false);
            if (this.filterMethod) {
                this.options = res;
                this.initData();
            }
        });
    }

    searchResult() {
        return new Promise((resolve) => {
            if (this.filterMethod) {
                this.filterMethod(this.search, resolve);
            } else {
                const treeRef: any = this.$refs.treeRef;
                treeRef.filter(this.search);
                resolve([]);
            }
        });
    }

    filterNode(value: any, data: any) {
        if (this.filterable && this.filterMethod) return true;
        if (!value) return true;
        return data.label.indexOf(value) !== -1;
    }

    handleNodeClick(item: any) {
        const { id }: any = item;
        if (!this.checkStrictly && item.children && item.children.length > 0) return;
        const _index = this.value.findIndex((cur: any) => cur === id);
        console.log(_index);
        if (_index === -1) {
            this.value.push(item.id);
            this.selectData.push(item);
        } else {
            const _itemIndex = this.selectData.findIndex((cur: any) => cur.id === id);
            this.value.splice(_index, 1);
            this.selectData.splice(_itemIndex, 1);
        }
        console.log(this.value);
    }

    handleDataClick(item: any) {
        if (!this.disabledValue.includes(item.id)) {
            const treeRef: any = this.$refs.treeRef;
            treeRef.setChecked(item.id);
        }
    }
}
</script>
<style scoped lang="scss">
.custom-modal {
    margin: 0;
    & /deep/ {
        .el-dialog {
            width: 800px;
        }
    }
    .dialog-footer {
        .el-button.sure {
            min-width: 100px;
        }
    }
    .tree-cascader-box {
        width: 100%;
        height: 7rem;
        @include flexLayout(flex, normal, normal);
        .tree-cascader__data-box {
            width: 100%;
            flex: 1;
            @include flexLayout(flex, normal, normal);
            flex-flow: column;
        }
        .tree-cascader__header {
            flex: 0 0 auto;
            height: 0.6rem;
            padding-bottom: .2rem;
            @include textEllipsis();
            @include flexLayout(flex, center, center);
        }
        .tree-cascader__body {
            flex: 1;
            height: calc(100% - 0.6rem);
            overflow: auto;
        }
        .tree-cascader__ul {
            width: 100%;
            .tree-cascader__li {
                padding: 0 0.2rem;
                height: 0.4rem;
                @include textEllipsis();
                @include flexLayout(flex, normal, center);
                cursor: pointer;
                & + .tree-cascader__li {
                    border-top: 1px solid #eee;
                }
                &:hover {
                    background: #eee;
                }
            }
        }
    }
}
</style>
